home *** CD-ROM | disk | FTP | other *** search
- PAGE ,132
- TITLE PR2FL - PRINTER REDIRECTION
- SUBTTL By Jim Kyle - May 28, 1985 - Version 1.0
- ;
- ; This program redirects PRN output to a file. The filename is
- ; supplied as a pathname when the program is invoked:
- ;
- ; PR2FL C:\FILES\PRTFIL.001
- ;
- ; It achieves this goal by opening the file, saving the file's
- ; DCB index (the content of its handle), and then faking an entry
- ; in the handle table of its Program Segment Prefix to show that
- ; the file is closed. Next, it extracts the content of the PRN
- ; handle and saves it on the stack, stuffs the file's DCB index
- ; into the PRN handle entry, and spawns a child copy of COMMAND.COM
- ; to permit continued operation. While the child copy is running,
- ; or any program called through the child copy is executing, all
- ; output directed to the PRN device via standard DOS interfaces will
- ; go instead to the redirection file.
- ;
- ; To terminate redirection, the child copy of COMMAND.COM is
- ; stopped via the EXIT command. Control then returns to PR2FL.COM,
- ; which closes the redirection file, restores the original PRN index
- ; value, displays a "Redirection Ended" message, and then returns
- ; control to the copy of COMMAND.COM from which it was invoked.
- ;
- ; This process inherently permits nesting. Each invocation of this
- ; program takes away approximately 4K of RAM for the duration of
- ; its execution (specifically, 3920 bytes). You can nest calls of
- ; PR2FL as deeply as you have RAM available, and at each EXIT they
- ; will automatically unwind themselves.
- ;
- ; To assemble, use MASM, LINK, and EXE2BIN. If you find this
- ; program useful, let me know. And if you find any bugs, by all
- ; means tell me about them!
- ; Jim Kyle
- ; 76703,762
- ; SysOp, CLM SIG (GO CLM-332)
- ;
- PAGE
- ;
- CODE SEGMENT PUBLIC 'CODE'
- ASSUME CS:CODE,DS:CODE,ES:CODE,SS:CODE
-
- ORG 0100H
-
- START: MOV SP,OFFSET STACK ;keep the stack safe
- CALL DOSVTST ;verify proper DOS version
- CALL GETPATH ;set up pointers to pathname
- JNZ HVPATH ;error check here if no path
- MOV DX,OFFSET NOPATH
- JMP SHORT FINI
- HVPATH: CALL REDIR ;get file and switch
- PUSH AX ;save for use at return
- MOV CMDLNP+2,CS ;initialize parm block
- MOV FCB1P+2,CS
- MOV FCB2P+2,CS
- MOV SAVSP,SP ;save stack pointer
- CALL GETCOM ;set up for COMSPEC (changes DS)
- CALL RELMEM ;release unneeded RAM
- MOV DX,SI ;DS:DX -> Pgm to run
- MOV BX,OFFSET PARMS ;ES:BX -> Parm Block
- MOV AX,4B00H ;AL=0 -> Execute program
- INT 21H
- MOV AX,CS ;restore segments
- MOV SS,AX
- MOV ES,AX
- MOV DS,AX
- MOV SP,SAVSP ;restore stack pointer
- MOV BX,4 ;PRN handle (file)
- MOV AH,3EH ;close the file
- INT 21H
- POP AX ;restore DCB indices
- MOV DI,1CH ;handle table offset for PRN in PSP
- MOV [DI],AH ;restore previous PRN
- MOV DX,OFFSET RTND ;return message
- FINI: PUSH CS ;restore DS
- POP DS
- MOV AH,9 ;send message
- INT 21H
- INT 20H ;then get out for keeps
- PAGE
- ;
- RELMEM:
- LAST = OFFSET STACK+17
- MOV AX,OFFSET LAST ;release surplus memory
- SHR AX,1 ;first convert to paragraphs
- SHR AX,1
- SHR AX,1
- SHR AX,1
- MOV BX,AX ;then stash in BX
- MOV AX,4A00H
- INT 21H
- RET
- ;
- SAVSP DW 0
- ;
- RTND DB 13,10,'Redirection Ended',13,10,36
- ;
- PARMS DW 0 ;env segment
- CMDLNP DW OFFSET CMDLIN,0 ;new command line
- FCB1P DW OFFSET FCB,0 ;new FCB1
- FCB2P DW OFFSET FCB,0 ;new FCB2
- ;
- CMDLIN DB CMDLEN ;length of command
- ; DB 'COMMAND /D' ;command line
- CMDLEN EQU $-CMDLIN-1
- DB 13 ;CR to terminate
- ;
- FCB DB 0
- DB ' '
- DW 0,0
- ;
- DB 126 DUP (?)
- STACK DW 0
- ;
- PAGE
- ;
- ; THIS CODE USED ONLY DURING SETUP, NO NEED TO KEEP IT
- ;
- ;---module dosvtst.asm
- ;
- ; verifies that DOS version is 2.0 or above, else aborts
- ;
- dosvtst:
- mov ah,30h ;version check
- int 21h
- xchg ah,al
- cmp ax,0200h ;2.0 and above
- jae vrsnok
- mov dx,offset wvm
- mov ah,9
- int 21h
- int 20h
- wvm db 'DOS 2.0 or above is required',13,10,'$'
- vrsnok: ret ;version is appropriate
- ;
- ;---end module dosvtst.asm
- ;
- PAGE
- ;
- ;---module getpath.asm
- ;
- ; converts first string of command tail into ASCIIZ
- ; pathname for DOS use.
- ; destroys registers AX, CX, DX, SI, and DI
- ; modifies flags
- ;
- GETPATH:
- CLD
- MOV SI,80H ;command tail in PSP
- LODSB ;get char count
- AND AL,127 ;test for no chars at all
- JZ PATH5 ;none, don't scan
- CBW
- MOV CX,AX ;else put into CX
- PATH0: MOV DX,SI ;save start offset
- MOV DI,SI
- LODSB ;ignore leading blank
- CMP AL,' '
- JA PATH2 ;non-blank, go look for end
- LOOP PATH0 ;leading blank, look more
- JMP SHORT PATH4 ;nothing found
- ;
- PATH1: MOV DI,SI ;save for case fix
- LODSB ;look for terminator
- CMP AL,' '
- JBE PATH4 ;found it
- PATH2: CMP AL,'a' ;not seen, check case
- JB PATH3
- CMP AL,'z'
- JA PATH3
- AND AL,5FH ;lowercase, make upper
- STOSB
- PATH3: LOOP PATH1
- INC DI ;to CR's location at EOS
- ;
- PATH4: XOR AL,AL ;force a zero
- MOV [DI],AL
- MOV AX,DI
- SUB AX,DX
- PATH5: RET ;path converted
- ;
- ; Z-flag is set if no pathname was present,
- ; else: AX = number of characters in pathname
- ; CX = 0
- ; DX points to pathname's first character
- ; SI points to character past terminator (or NULL if no more)
- ; DI points to terminating NULL of pathname
- ;
- ;---end module getpath.asm
- PAGE
- ;
- GETCOM: MOV SI,02CH ;search Environment for COMSPEC
- MOV SI,[SI]
- MOV DS,SI
- MOV PARMS,SI ;use parent's environment
- MOV SI,0
- LODSB
- NXT: MOV BX,OFFSET ENVSTR
- CMP AL,ES:[BX]
- JNZ SKIP ;no initial match
- MOV CX,7
- CHK: LODSB
- INC BX
- CMP AL,ES:[BX]
- JNZ SKIP ;failed after start
- LOOP CHK
- RET ;if we get here it's found
- ;
- ENVSTR DB 'COMSPEC='
- ;
- SKIP: LODSB ;find EOS
- OR AL,AL
- JNZ SKIP
- LODSB ;test for end of Environment
- OR AL,AL
- JNZ NXT ;more to check
- MOV DX,OFFSET NOENV ;hit the end!
- JMP FINI
- ;
- NOPATH DB 13,10,'Pathname is required',13,10,36
- NOENV DB 13,10,'No COMSPEC= found',13,10,36
- ;
- PAGE
- ;
- REDIR: MOV CX,0
- MOV AH,3CH ;create file
- INT 21H
- JC DSKERR
- MOV BX,AX ;handle
- MOV SI,18H ;handle table offset in PSP
- MOV AL,[BX][SI] ;DCB index for new file
- MOV [BX][SI],BYTE PTR 255 ;mark its handle as closed
- MOV AH,[SI][4] ;DCB index for PRN handle
- MOV [SI][4],AL ;set new file in as PRN
- RET ;if no error (indices in AX)
- ;
- DSKERR:
- cmp ax,19
- jl valerr
- mov dx,offset uem
- jmp short abrt
- valerr: add ax,ax
- mov bx,offset emt
- add bx,ax
- mov dx,[bx]
- abrt: mov ah,9
- int 21h
- mov dx,offset emg2
- mov ah,9
- int 21h
- done: int 20h
- ;
- emg2 db '.',13,10
- db 'ABORTED.',7,13,10,'$'
- ;
- emt dw uem,em1,em2,em3,em4,em5,em6,em7
- dw em8,em9,em10,em11,em12,em13,uem
- dw em15,em16,em17,em18
- ;
- uem db 'Unknown error code$'
- em1 db 'Bad call$'
- em2 db 'No file found$'
- em3 db 'Path not found$'
- em4 db 'Out of handles$'
- em5 db 'Access denied$'
- em6 db 'Handle bad$'
- em7 db 'Memory fouled$'
- em8 db 'No more RAM$'
- em9 db 'Bad adr$'
- em10 db 'Bad ENV$'
- em11 db 'Bad format$'
- em12 db 'Bad access code$'
- em13 db 'Bad data$'
- em15 db 'Drive not valid$'
- em16 db 'Dir error$'
- em17 db 'Wrong device$'
- em18 db 'Out of files$'
- ;
- CODE ENDS
- END START